<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      .box {
        width: 450px;
        margin: 50px auto;
        border: 1px solid black;
        padding: 2px;
      }
      table,
      th,
      td {
        border: 1px solid black;
        border-collapse: collapse;
        text-align: center;
        padding: 1px;
      }

      th.narrow {
        width: 100px;
      }

      th.wide {
        width: 150px;
      }

      tr.odd,
      tr.odd input {
        background-color: rgb(200, 201, 208);
      }

      .ip {
        width: 90px;
        margin-bottom: 5px;
        border: none;
        text-align: center;
        outline: none;
      }

      td > button {
        padding: 2px 5px;
      }

      #btnAdd,
      #btnSwitch {
        width: 100%;
      }

      .hide {
        display: none;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <button id="btnSwitch">切换表格/JSON</button>
      <table>
        <thead>
          <!-- <th class="narrow">name</th>
          <th class="narrow">age</th>
          <th class="narrow">gender</th>
          <th class="wide">actions</th> -->
        </thead>
        <tbody>
          <!-- <tr>
            <td>Jack</td>
            <td>18</td>
            <td>男</td>
            <td>
              <button>编辑/保存</button>
              <button>删除</button>
            </td>
          </tr> -->
        </tbody>
      </table>
      <button id="btnAdd">+</button>
      <p id="pJson" class="hide">JSON</p>
    </div>

    <script>
      var arr = [
        {
          name: "Jack",
          age: 18,
          gender: "男",
        },
        {
          name: "Rose",
          age: 20,
          gender: "女",
        },
        {
          name: "Top",
          age: 22,
          gender: "男",
        },
      ];

      /* 找出元素 */
      var pJson = document.querySelector("#pJson");

      var table = document.querySelector("table");
      var thead = table.querySelector("thead");
      var tbody = table.querySelector("tbody");
      var btnAdd = document.querySelector("#btnAdd");
      var btnSwitch = document.querySelector("#btnSwitch");

      /* 渲染表头 */
      function renderThead() {
        // 随便拿出一个数据项
        var obj = arr[0];

        // 预置一个theadHtml字符串
        var theadHtml = "";

        // 遍历所有的key
        for (var key in obj) {
          // 每个key对应一个th
          theadHtml += `<th class="narrow">${key}</th>`;
        }

        // 最后再暴力添加一列操作列
        theadHtml += `<th class="wide">actions</th>`;
        console.log(theadHtml);

        // 将拼接好的theadHtml设置给thead
        thead.innerHTML = theadHtml;
      }
      renderThead();

      /* 渲染数据 */
      function renderTable() {
        tbodyHtml = "";

        // 遍历数据
        arr.forEach(function (item, index) {
          // 每个数据项对应一个tr
          tbodyHtml += `<tr ${index % 2 === 1 && 'class="odd"'} mode="read">`;

          for (var key in item) {
            // 每个key-value对应一个td
            tbodyHtml += `
    <td>
      <input class="ip" type="text" value="${item[key]}" disabled="true">
    </td>`;
          }

          // 暴力拼接操作按钮td
          tbodyHtml += `
  <td>
    <button class="btnEdit">编辑/保存</button>
    <button class="btnDelete">删除</button>
  </td>
  `;

          // 收起tr
          tbodyHtml += "</tr>";
        });

        // 将拼接好的tbodyHtml设置给tbody
        tbody.innerHTML = tbodyHtml;

        // 设置按钮的点击事件
        tbody.querySelectorAll(".btnDelete").forEach(function (btn, index) {
          btn.onclick = function () {
            // console.log(index);
            // 删除对应行的数据
            arr.splice(index, 1);
            // 重新渲染
            renderData();
          };
        });

        tbody.querySelectorAll(".btnEdit").forEach(function (btn, index) {
          btn.onclick = function () {
            // 当前行在阅读模式/编辑模式下来回切换
            var tr = this.parentNode.parentNode;
            tr.setAttribute(
              "mode",
              // 当前模式阅读乎?编辑模式:阅读模式
              tr.getAttribute("mode") === "read" ? "edit" : "read"
            );

            /* 决定input框是否可用 */
            // 找出tr下的所有input框
            var ips = tr.querySelectorAll("input");
            if (tr.getAttribute("mode") === "read") {
              // 阅读模式下ips皆不可用
              ips.forEach(function (ip, i) {
                ip.setAttribute("disabled", "1");
              });
            } else {
              // 编辑模式下ips皆可用
              ips.forEach(function (ip, i) {
                ip.removeAttribute("disabled");
              });
            }

            /* 模式由编辑转阅读时 => 保存数据 */
            if (tr.getAttribute("mode") === "read") {
              // 拿出当前行的所有用户输入
              // Array.from者 伪数组进去 真数组粗来
              var ipsArr = Array.from(ips);

              // 将input数组 映射为对应的value数组
              var values = ipsArr.map(
                // 处理器:旧元素进去 新元素出来
                function (ip, index) {
                  return ip.value;
                }
              );
              saveData(index, values);
            }
          };
        });
      }

      function renderJson() {
        pJson.innerText = JSON.stringify(arr);
      }

      function renderData() {
        renderTable();
        renderJson();
      }
      renderData();

      /* 保存数据 */
      function saveData(index, values) {
        var obj = arr[index];
        obj.name = values[0];
        obj.age = values[1];
        obj.gender = values[2];
        console.log(arr);

        // 重新渲染一下JSON（表格无需重绘）
        renderJson()
      }

      /* 事件处理 */
      btnAdd.onclick = function () {
        // 错误示范！！！引用传递排头兵的地址（浅拷贝，一拖二）
        // var obj = arr[0]

        // 造一条空数据
        // 基于第一条数据 创建一个深拷贝副本 清空value
        var obj = JSON.parse(JSON.stringify(arr[0]));
        for (var key in obj) {
          obj[key] = "";
        }

        // 给arr追加一条空数据
        arr.push(obj);

        // 重新渲染数据
        renderData();

        // 非常不要不要脸地帮用户在当前行点击一下【编辑】 以激活当前行
        // 找出最后一个编辑按钮并点击之
        tbody.querySelectorAll(".btnEdit")[arr.length - 1].onclick();
      };

      btnSwitch.onclick = function () {
        /* 表格与JSON两大DOM元素 切换hide class（有则拿掉无责加之） */
        table.classList.toggle("hide");
        btnAdd.classList.toggle("hide");
        pJson.classList.toggle("hide");
      };
    </script>
  </body>
</html>
